package edu.mtu.citizenscience.ethnography;

import java.io.IOException;
import java.text.DateFormat;
import java.util.Comparator;
import java.util.List;

import edu.mtu.citizenscience.ethnography.database.Interview;
import edu.mtu.citizenscience.ethnography.uploader.EthnographyUploadService;
import edu.mtu.citizenscience.ethnography.util.DataServiceActivity;
import edu.mtu.citizenscience.ethnography.util.LoginDialogFragment;
import edu.mtu.citizenscience.ethnography.util.UploadDialogFragment;
import edu.mtu.citizenscience.ethnography.util.Util;

import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Typeface;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class InterviewListActivity extends DataServiceActivity {

	private static final String LOG_TAG = "InterviewListActivity";

	private InterviewAdapter adapter = null;

	private ListView listView;

	private Button sortByNameButton;
	private Button sortByLocationButton;
	private Button sortByDateButton;

	private Button viewButton;
	private Button deleteButton;
	private Button uploadButton;

	private View selectedItemView;
	private int selectedItemPos;

	private int unselectedItemColor;
	private int selectedItemColor;
	private int unselectedTextColor;
	private int selectedTextColor;

	private BroadcastReceiver receiver = null;
	private IntentFilter intentFilter = new IntentFilter(EthnographyUploadService.UPLOAD_SERVICE);
	private LocalBroadcastManager manager;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		Log.d(LOG_TAG, LOG_TAG + " is being created");

		setContentView(R.layout.activity_interview_list);

		unselectedItemColor = getResources().getColor(R.color.default_background_color);
		selectedItemColor = getResources().getColor(R.color.item_selected_color);
		unselectedTextColor = getResources().getColor(R.color.default_text_color);
		selectedTextColor = getResources().getColor(R.color.selection_text_color);

		listView = (ListView) findViewById(R.id.interviewList);
		listView.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> parent, View view, int position,
					long id) {
				if (position == selectedItemPos) {
					// "Double-click" so view the selected one
					viewInterview(viewButton);
				} else {
					if (selectedItemView != null) {
						selectedItemView.setBackgroundColor(unselectedItemColor);
						TextView nameView = (TextView) selectedItemView.findViewById(R.id.nameView);
						TextView dateView = (TextView) selectedItemView.findViewById(R.id.dateView);
						TextView locationView = (TextView) selectedItemView.findViewById(R.id.locationView); 

						nameView.setTextColor(unselectedTextColor);
						dateView.setTextColor(unselectedTextColor);
						locationView.setTextColor(unselectedTextColor);
					}

					selectedItemView = view;
					selectedItemPos = position;

					viewButton.setEnabled(true);
					deleteButton.setEnabled(true);
					uploadButton.setEnabled(true);

					selectedItemView.setBackgroundColor(selectedItemColor);
					TextView nameView = (TextView) selectedItemView.findViewById(R.id.nameView);
					TextView dateView = (TextView) selectedItemView.findViewById(R.id.dateView);
					TextView locationView = (TextView) selectedItemView.findViewById(R.id.locationView); 

					nameView.setTextColor(selectedTextColor);
					dateView.setTextColor(selectedTextColor);
					locationView.setTextColor(selectedTextColor);
				}
			}
		}
				);


		sortByNameButton = (Button) findViewById(R.id.sort_name_button);
		sortByLocationButton = (Button) findViewById(R.id.sort_location_button);
		sortByDateButton = (Button) findViewById(R.id.sort_date_button);

		viewButton = (Button) findViewById(R.id.view_item_button);
		deleteButton = (Button) findViewById(R.id.delete_item_button);
		uploadButton = (Button) findViewById(R.id.upload_item_button);
		uploadButton.setEnabled(false);

		manager = LocalBroadcastManager.getInstance(this);
	}

	@Override
	protected void onStart() {
		Log.d(LOG_TAG, LOG_TAG + " is starting");

		selectedItemView = null;
		selectedItemPos = -1;

		viewButton.setEnabled(false);
		deleteButton.setEnabled(false);
		uploadButton.setEnabled(false);

		super.onStart();
	}

	@Override
	protected void onResume() {
		super.onResume();
		if (receiver != null) {
			manager.registerReceiver(receiver, intentFilter);
		}
	}

	@Override
	protected void onPause() {
		super.onPause();
		if (receiver != null) {
			manager.unregisterReceiver(receiver);
		}
	}

	@Override
	protected void onDestroy() {
		Log.d(LOG_TAG, LOG_TAG + " is being destroyed");

		super.onDestroy();
	}

	@Override
	protected void performDatabaseOperation() {
		List<Interview> interviews = getService().getAllInterviews();
		InterviewAdapter adapter = new InterviewAdapter(getApplicationContext(), interviews);
		this.adapter = adapter;
		listView.setAdapter(adapter);
		if (interviews.size() == 0) {
			// Disable sort buttons if there's nothing to sort
			sortByNameButton.setEnabled(false);
			sortByLocationButton.setEnabled(false);
			sortByDateButton.setEnabled(false);
		} else {
			sortByNameButton.setEnabled(true);
			sortByLocationButton.setEnabled(true);
			sortByDateButton.setEnabled(true);
		}
	}

	public void sortByName(View view) {
		if (adapter != null) {
			setNothingSelected();
			adapter.sort(new Comparator<Interview>() {

				@Override
				public int compare(Interview lhs, Interview rhs) {
					int result;
					// Comparison criteria: stories are sorted by title. If title is not defined,
					// sort by name. Stories with titles come before stories with names.
					if (lhs.getStoryTitle().equals("")) {
						if (rhs.getStoryTitle().equals("")) {
							result = lhs.getSubjectName().compareTo(rhs.getSubjectName());
						} else {
							result = 1;
						}
					} else if (rhs.getStoryTitle().equals("")) {
						result = -1;
					} else {
						result = lhs.getStoryTitle().compareTo(rhs.getStoryTitle());
					}
					return result;
				}
			});
			adapter.notifyDataSetChanged();
		}
	}

	public void sortByLocation(View view) {
		if (adapter != null) {
			setNothingSelected();
			adapter.sort(new Comparator<Interview>() {

				@Override
				public int compare(Interview lhs, Interview rhs) {
					return lhs.getLocationName().compareTo(rhs.getLocationName());
				}
			});
			adapter.notifyDataSetChanged();
		}
	}

	public void sortByDate(View view) {
		if (adapter != null) {
			setNothingSelected();
			adapter.sort(new Comparator<Interview>() {

				@Override
				public int compare(Interview lhs, Interview rhs) {
					return lhs.getDate().compareTo(rhs.getDate());
				}

			});

			adapter.notifyDataSetChanged();
		}
	}

	public void viewInterview(View view) {
		Intent intent = new Intent(view.getContext(), InterviewDetailActivity.class);
		intent.putExtra(InterviewDetailActivity.ID_KEY, adapter.getItem(selectedItemPos).getID());
		startActivityForResult(intent, 0);
	}

	public void deleteInterview(View view) {
		// Verify an item is selected
		if (selectedItemPos >= 0) {
			// Build the alert dialog
			Log.d(LOG_TAG, String.format("Attempting to delete item %d", selectedItemPos));
			AlertDialog.Builder builder = new AlertDialog.Builder(this);
			builder.setMessage(getString(R.string.delete_message));
			builder.setPositiveButton(R.string.delete_ok, new OnClickListener() {
				@Override
				public void onClick(DialogInterface dialog, int which) {
					AlertDialog.Builder builder = new AlertDialog.Builder(InterviewListActivity.this);
					builder.setMessage(R.string.delete_media_message);
					builder.setPositiveButton(R.string.delete_media_keep, new OnClickListener() {

						@Override
						public void onClick(DialogInterface dialog, int which) {
							getService().removeInterviewAndKeepMedia(adapter.getItem(selectedItemPos));
							adapter.remove(adapter.getItem(selectedItemPos));
						}
					});
					builder.setNeutralButton(R.string.delete_ok, new OnClickListener() {

						@Override
						public void onClick(DialogInterface dialog, int which) {
							try {
								getService().removeInterview(adapter.getItem(selectedItemPos));
								adapter.remove(adapter.getItem(selectedItemPos));
							} catch (IOException e) {
								Log.e(LOG_TAG, 
										String.format("Deleting interview %d threw an exception", 
												selectedItemPos), 
												e);
								fail(R.string.io_error);
							}
						}
					});
					builder.setNegativeButton(R.string.cancel, new OnClickListener() {

						@Override
						public void onClick(DialogInterface dialog, int which) {
							// TODO Auto-generated method stub

						}
					});
					builder.create().show();
				}
			});
			builder.setNegativeButton(R.string.cancel, new OnClickListener() {

				@Override
				public void onClick(DialogInterface dialog, int which) {
					// Do nothing

				}
			});
			builder.create().show();
		} else {
			fail(R.string.unknown_error);
		}
	}

	public void uploadInterview(View view) {

		if (Util.isLoggedIn(this)) {
			// Are logged in, so go ahead and upload
			UploadDialogFragment fragment = new UploadDialogFragment();
			Bundle args = new Bundle();
			args.putInt(UploadDialogFragment.ID, adapter.getItem(selectedItemPos).getID());
			fragment.setArguments(args);
			fragment.show(getSupportFragmentManager(), UploadDialogFragment.FRAG_TAG);
		} else {
			receiver = new LoginBroadcastReceiver();
			manager.registerReceiver(receiver, intentFilter);

			// XXX This should probably be done with setArguments but I'm in a hurry
			LoginDialogFragment fragment = new LoginDialogFragment();
			fragment.setCallingActivity(this);
			fragment.show(getSupportFragmentManager(), LoginDialogFragment.FRAG_TAG);
		}
	}

	private void setNothingSelected() {
		selectedItemPos = -1;
		selectedItemView = null;
		viewButton.setEnabled(false);
		uploadButton.setEnabled(false);
		deleteButton.setEnabled(false);
	}

	private class InterviewAdapter extends ArrayAdapter<Interview> {
		private final Context context;

		public InterviewAdapter(Context context, List<Interview> values) {
			super(context, R.layout.interview_item_view, values);
			this.context = context;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
			View itemView = inflater.inflate(R.layout.interview_item_view, parent, false);
			TextView nameView = (TextView) itemView.findViewById(R.id.nameView);
			TextView dateView = (TextView) itemView.findViewById(R.id.dateView);
			TextView locationView = (TextView) itemView.findViewById(R.id.locationView);

			Interview interview = getItem(position);
			String title = interview.getStoryTitle();
			if (!title.equals("")) {
				nameView.setTypeface(null, Typeface.ITALIC);
				nameView.setText(title);
			} else {
				String name = interview.getSubjectName().getReversedFullName();
				if (name.equals("")) {
					nameView.setTypeface(null, Typeface.ITALIC);
					nameView.setText("No name specified");
				} else {
					nameView.setTypeface(null, Typeface.NORMAL);
					nameView.setText(name);
				}
			}
			String location = interview.getLocationName();
			if (location.equals("")) {
				locationView.setTypeface(null, Typeface.ITALIC);
				locationView.setText("No location specified");
			} else {
				locationView.setTypeface(null, Typeface.NORMAL);
				locationView.setText(location);
			}
			String date = DateFormat.getDateInstance().format(interview.getDate());
			if (date.equals("")) {
				dateView.setTypeface(null, Typeface.ITALIC);
				dateView.setText("No date specified");
			} else {
				dateView.setTypeface(null, Typeface.NORMAL);
				dateView.setText(date);
			}
			return itemView;
		}

		@Override
		public void remove(Interview object) {
			super.remove(getItem(selectedItemPos));
			notifyDataSetChanged();
			setNothingSelected();
			if (getCount() == 0) {
				sortByDateButton.setEnabled(false);
				sortByNameButton.setEnabled(false);
				sortByLocationButton.setEnabled(false);
			}
		}

	}

	public class LoginBroadcastReceiver extends BroadcastReceiver {

		@Override
		public void onReceive(Context context, Intent intent) {
			String result = intent.getStringExtra(EthnographyUploadService.OUTPUT_RESULT);
			int id = Util.loginStringIDs.get(result);
			Toast toast = Toast.makeText(context, id, Toast.LENGTH_SHORT);
			toast.show();
			manager.unregisterReceiver(receiver);
			receiver = null;
		}

	}

}
